#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat process(Mat& input);  //图像处理函数，返回直方图均衡化之后的图像
int grey[256] = {0};      //统计各个灰度级的像素点出现的频数
// Mat calcGrayHist(Mat& image);    // huizhihuiduzhifantu
double grey_prob[256] = {0};     //定义数组存储各个灰度级出现的概率
double grey_sumprob[256] = {0};  //求解概率密度
int grey_result[256] = {0};      //记录均很化之后的结果
int grey_sum = 0;                //定义数组存储总的像素数
int main() {
    Mat src = imread("/home/dao/桌面/demo/src/first.png");
    Mat m1;
    cvtColor(src, m1, COLOR_BGR2GRAY);
    Mat m2 = process(m1);
    // Mat hist1 = calcGrayHist(m1);
    // Mat hist2 = calcGrayHist(m2);
    imshow("begin", m1);
    imshow("last", m2);
    // imshow("begin", hist1);
    // imshow("last", hist2);
    // std::cout << m2 << std::endl;
    waitKey(0);
    return 0;
}

Mat process(Mat& image) {
    Mat image_copy = image.clone();
    grey_sum = image.cols * image.rows;
    //遍历图像每一个像素点，统计各个灰度级像素点出现的次数
    for (int i = 0; i < image_copy.rows; i++) {
        uchar* p = image_copy.ptr<uchar>(i);
        for (int j = 0; j < image_copy.cols; j++) {
            int vaule = p[j];
            grey[vaule]++;
        }
    }
    //计算概率，根据频次计算
    for (int i = 0; i < 256; i++) {
        grey_prob[i] = double(grey[i]) / grey_sum;
    }
    //得到概率密度分布
    grey_sumprob[0] = grey_prob[0];
    for (int i = 1; i < 255; i++) {
        grey_sumprob[i] = grey_sumprob[i - 1] + grey_prob[i];
    }
    //根据结论计算得到最后结果
    for (int i = 0; i < 256; i++) {
        grey_result[i] = (uchar)(255 * grey_sumprob[i] + 0.5);
    }
    //更新图像的像素值
    for (int i = 0; i < image_copy.rows; i++) {
        uchar* p = image_copy.ptr<uchar>(i);
        for (int j = 0; j < image_copy.cols; j++) {
            p[j] = grey_result[p[j]];
        }
    }
    return image_copy;
}
// Mat calcGrayHist(Mat& image) {
//     // Mat histogram = image.clone();
//     Mat histogram = Mat::zeros(Size(256, 1), CV_8UC3);
//     // //注意，Size对应的是x和y，也就是第一个元数是矩阵的列数
//     int rows = image.rows;  //输入图像的行数
//     int cols = image.cols;  //输入图像的列数
//     for (int i = 0; i < rows; i++) {
//         uchar* p1 = image.ptr<uchar>(i);
//         for (int j = 0; j < cols; j++) {
//             int index = p1[j];                 //获取每个点的像素值
//             histogram.at<int>(0, index) += 1;  //获取了一个像素值，在相应的位置上加1
//         }
//     }
//     return histogram;
// }
